package com;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 *   编写一个程序，开启3个线程，这3个线程的Name分别为A、B、C，每个线程将自己的Name在屏幕上打印10遍，
 *   要求输出结果必须按ABC的顺序显示；如：ABCABCABC….依次递推
 */
public class TestJUC {
    public static void main(String[] args) {
        ThreadResource threadResource = new ThreadResource();
        /*for (int i = 0; i < 10; i++) {
            new Thread(()->{
                threadResource.printA();
                threadResource.printB();
                threadResource.printC();
            },String.valueOf(i)).start();
        }*/
            new Thread(new ThreadA(threadResource),"A").start();
            new Thread(new ThreadB(threadResource),"B").start();
            new Thread(new ThreadC(threadResource),"C").start();
    }
}

class ThreadResource{
    private int number = 1;//1代表A 2代表B 3代表C
    private Lock lock = new ReentrantLock();
    private Condition c1 = lock.newCondition();
    private Condition c2 = lock.newCondition();
    private Condition c3 = lock.newCondition();
    public void printA(){
        try{
            lock.lock();
            while(number!=1){
                c1.await();
            }
            System.out.print(Thread.currentThread().getName());
            number = 2;
            c2.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void printB(){
        try{
            lock.lock();
            while(number!=2){
                c2.await();
            }
            System.out.print(Thread.currentThread().getName());
            number = 3;
            c3.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
    public void printC(){
        try{
            lock.lock();
            while(number!=3){
                c3.await();
            }
            System.out.println(Thread.currentThread().getName());
            number = 1;
            c1.signal();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

}

class ThreadA implements Runnable{
    private ThreadResource threadResource;
    public ThreadA(ThreadResource threadResource){
        this.threadResource = threadResource;
    }
    public void run() {

        for (int i = 0; i < 9; i++) {threadResource.printA();}
    }
}
class ThreadB implements Runnable{
    private ThreadResource threadResource;
    public ThreadB(ThreadResource threadResource){
        this.threadResource = threadResource;
    }
    public void run() {
        for (int i = 0; i < 9; i++) {
            threadResource.printB();
        }
    }
}
class ThreadC implements Runnable{
    private ThreadResource threadResource;
    public ThreadC(ThreadResource threadResource){
        this.threadResource = threadResource;
    }
    public void run() {
        for (int i = 0; i < 9; i++) {

            threadResource.printC();
        }
    }
}


